package sg.nus.iss.vmcs.controllers;

import sg.nus.iss.vmcs.VMCSException;
import sg.nus.iss.vmcs.gui.MaintenancePanel;
import sg.nus.iss.vmcs.gui.MessageDialog;
import sg.nus.iss.vmcs.gui.SimulatorControlPanel;
import sg.nus.iss.vmcs.models.StoreItem;
import sg.nus.iss.vmcs.utils.StoreType;

/**
 * Maintenance Controller for controlling the Maintenance Panel
 * <br><br>
 * @author Olivo Miotto
 * @author Pang Pingli
 */
public class MaintenanceController {
	
	/** Main Controller */
    private MainController mCtrl;
    
    /** Access Manager managed by this controller */
    private AccessManager accessMgr;
    
    /** Maintenance Panel managed by this controller */
    private MaintenancePanel mPanel;
   
    /**
     * Creates an instance of the MaintenanceController
     * @param mctrl Reference to the Main Controller
     */
    public MaintenanceController (MainController  mctrl) {
    	mCtrl = mctrl;
    	accessMgr = new AccessManager(this);
    }

    /**
     * Returns the reference to the main controller
     * @return Main Controller
     */
    public MainController getMainController(){
    	return mCtrl;
    }
    
    /**
     * Returns the reference to the main controller
     * @return Access Manager
     */
    public AccessManager getAccessManager(){
        return accessMgr;
    }

    /**
     * Returns the reference to the maintenance panel
     * @return Maintenance Panel
     */
    public MaintenancePanel getMaintenancePanel(){
    	return mPanel;
    }

    /**
     * Logs in the maintainer into the system
     * @param isPasswordCorrect True if password is correct, false if otherwise
     */
    public void loginMaintainer(boolean isPasswordCorrect) {
        mPanel.clearPassword();
        mPanel.displayPasswordState(isPasswordCorrect);
        
        if(isPasswordCorrect) {
        	mPanel.setActive(MaintenancePanel.PSWD, false);
        	mPanel.setActive(MaintenancePanel.WORKING, true);
            
        	//Setting statuses of related elements
        	mCtrl.getMachineryController().setDoorStatus(false);
        	mCtrl.getSimulatorControlPanel().setActive(SimulatorControlPanel.ACT_CUSTOMER, false);
        }
    }
    
    /**
     * Sets the price of a drink as determined by the maintainer
     * Invoked by Price Display Listener
     */
    public void setPrice(int price){
    	mCtrl.getStoreController().setPrice(mPanel.getDrinksDisplay().getCurIdx(), price);
    	mPanel.getDrinksDisplay().getPriceDisplay().setValue(price);
    }
    
    /**
     * Used to get the total number of coins of a selected denomination
     * Invoked by CoinDisplayListener
     */
    public void displayCoin(int idx) {
    	try {
    		mPanel.getCoinDisplay().displayQty(idx,
    			mCtrl.getStoreController().getStore(StoreType.CASH).getStoreItem(idx).getQuantity());
    	}
    	catch(VMCSException ve) {
    		System.out.println("Exception in display coin: " + ve.getStackTrace());
    	}
    }
    
    /**
     * Gets drink stock value and prices of a specific brand and displays it
     * Invoked by the DrinkDisplayListener;
     * @param idx Index of the drink brand
     */
    public void displayDrinks(int idx) {
    	try {
    		StoreItem dsi = mCtrl.getStoreController().getStore(StoreType.DRINKS).getStoreItem(idx);
			mPanel.getDrinksDisplay().displayQty(idx, dsi.getQuantity());
			mPanel.displayPrice(dsi.getContent().getValue());
		} 
    	catch (VMCSException e) {
    		System.out.println("Exception in display drinks: " + e.getStackTrace());
		}
    }    
    
    /**
     * Displays the total cash held in the cash store
     *  Invoked by TotalCashButtonListener
     */
    public void getTotalCash(){
    	mPanel.displayTotalCash(mCtrl.getStoreController().getTotalCash());
    }
    
    /**
     * Logs a maintainer out of the system
     * Invoked by the exit button listener;
     */
    public void logoutMaintainer(){
       if(! mCtrl.getMachineryController().isDoorClosed()) {
            new MessageDialog(mPanel, MessageDialog.LOCK_DOOR);
       }
       else {
    	   mPanel.setActive(MaintenancePanel.DIALOG, true);
       }
    }
    
    /**
     * Closes down the Maintenance Controller
     * @return True if close down succeeds, false if otherwise
     */
    public boolean closeDown() {
        if(mPanel == null) {
        	return true;
        }
        else if(! mCtrl.getMachineryController().isDoorClosed()) {
        	new MessageDialog(mPanel, MessageDialog.LOCK_DOOR);
        	return false;
        }
        else
        {
	        mPanel.closeDown();
	        mCtrl.getSimulatorControlPanel().setActive(SimulatorControlPanel.ACT_MAINTAINER, true);
	        return true;
        }
    }
    
    /**
     * setup the maintenance panel and display it.
     */
    public void displayMaintenancePanel() {
    	if(mPanel == null) {
    		mPanel = new MaintenancePanel(mCtrl.getSimulatorControlPanel(), this);
    	}
    	
    	mPanel.display();
    	mPanel.setActive(MaintenancePanel.DIALOG, true);
    }
    
    /**
     * Gets all the cash from store and set store cash 0;
     * Invoked by TransferCashButtonListener
     */
    public void transferAll() {
    	try {
    		mPanel.displayCoins(mCtrl.getStoreController().transferAll());
    		mPanel.updateCurrentQtyDisplay(StoreType.CASH, 0);
    	}
    	catch (VMCSException e) {
            System.out.println("MaintenanceController.transferAll:" + e);
        }
    }
}